/*
 * (C) Copyright 2006-2010 Nuxeo SAS (http://nuxeo.com/) and contributors.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * Contributors:
 *     bstefanescu
 */
package org.nuxeo.gwt.habyt.upload.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.io.FilenameUtils;

/**
 * A file being uploaded
 * 
 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
 * 
 */
public class UploadedFile implements ProgressListener, FileHolder {

    protected String id;

    protected volatile int progress;

    protected volatile FileItem file;

    public UploadedFile(String id) {
        this.id = id;
    }

    public void setFile(FileItem file) {
        this.file = file;
    }

    public FileItem getFile() {
        return file;
    }

    public String getId() {
        return id;
    }

    @Override
    public long getLength() {
        FileItem file = this.file;
        return file == null ? -1 : file.getSize();
    }

    @Override
    public String getContentType() {
        FileItem file = this.file;
        return file == null ? "application/octet-stream"
                : file.getContentType();
    }

    @Override
    public void writeTo(OutputStream out) throws IOException {
        FileItem file = this.file;
        if (file == null) {
            return;
        }
        InputStream in = file.getInputStream();
        try {
            long len = file.getSize();
            if (len < 0 && len > 1024 * 1024) { // 1MB
                len = 1024 * 1024;
            }
            byte[] buf = new byte[(int) len];
            int r = in.read(buf);
            while (r > -1) {
                if (r > 0) {
                    out.write(buf, 0, r);
                }
                r = in.read(buf);
            }
        } finally {
            in.close();
        }
    }

    public int getProgress() {
        return progress;
    }

    @Override
    public void update(long pBytesRead, long pContentLength, int pItems) {
        if (pBytesRead == 0) {
            progress = 0;
        } else {
            if (pContentLength == -1) {
                // let suppose there is still 1M to upload..
                pContentLength = pBytesRead + 1024 * 1024;
            }
            progress = (int) ((pBytesRead * 100) / pContentLength);
        }
        // System.out.println(">>>>>>>>>> progress: " + id + " -> " + progress);
    }

    public void delete() {
        FileItem file = this.file;
        if (file != null) {
            file.delete();
        }
    }

    @Override
    public String getFilename() {
        FileItem file = this.file;
        if (file != null) {
            String name = file.getName();
            if (name != null) {
                return FilenameUtils.getName(name);
            }
        }
        return null;
    }

    @Override
    public String toString() {
        return id + " : " + progress;
    }
}
